﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Net;
using Intorise.Common;

namespace Model
{
    /// <summary>
    /// 服务器返回的消息
    /// </summary>
    public class Message
    {
        public MessageTypeEnum MessageType { get; set; }

        /// <summary>
        /// 数据长度
        /// </summary>
        public int Length { get; set; }
        /// <summary>
        /// 消息数据
        /// </summary>
        public byte[] Data { get; set; }
        /// <summary>
        /// 32位整数消息编码表示消息的用途
        /// </summary>
        public int Type { get; set; }
    }

    public class CurrentMapMsg : Message
    {
        public ushort ID { get; set; }
        public CurrentMapMsg(byte[] Data)
        {
            MessageType = MessageTypeEnum.CurrentMap;
            Type = 0x018706;
            this.Data = Data;
            ID = (ushort)IPAddress.NetworkToHostOrder(BitConverter.ToInt16(Data, 0));
        }
    }

    /// <summary>
    /// 进入地图
    /// </summary>
    public class MapEnteredMsg : Message
    {
        public MapEnteredMsg(byte[] Data)
        {
            MessageType = MessageTypeEnum.MapEntered;
            Type = 0x00018B00;
            this.Data = Data;
            Line = Data[0] / 2;
            X = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(Data, 1));
            Y = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(Data, 3));
            Location = new Point(X / 25, Y / 25);
        }
        public short X { get; private set; }
        public short Y { get; private set; }
        public Point Location { get; private set; }

        public int Line { get; private set; }
    }

    /// <summary>
    /// 位置变化
    /// </summary>
    public class LocationChangedMsg : Message
    {
        public LocationChangedMsg(byte[] Data)
        {
            MessageType = MessageTypeEnum.LocationChanged;
            Type = 0x00018B03;
            this.Data = Data;
            UserID = DataPackager.GetHostData64(Data, 0);
            X = DataPackager.GetHostData16(Data, 9);
            Y = DataPackager.GetHostData16(Data, 11);
            Location = new Point(X / 25, Y / 25);
        }
        public short X { get; private set; }
        public short Y { get; private set; }
        public long UserID { get; private set; }
        public Point Location { get; private set; }
    }

    /// <summary>
    /// 登陆消息
    /// </summary>
    public class LoginSuccessMsg : Message
    {
        public short Flag { get; private set; }
        /// <summary>
        /// 玩家编号
        /// </summary>
        public long ID { get; private set; }
        public string Name { get; private set; }
        public int Level { get; private set; }
        public byte[] Version { get; private set; }

        public LoginSuccessMsg(byte[] Data)
        {
            MessageType = MessageTypeEnum.LoginSuccess;
            Type = 0x00018705;
            if (Data[2] == 0)
            {
                ID = 0;
                return;
            }
            Flag = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(Data, 0));
            ID = IPAddress.NetworkToHostOrder(BitConverter.ToInt64(Data, 2));
            Version = Data.Skip(10).Take(1).ToArray();
            int length = DataPackager.GetHostData16(Data, 11);
            Name = Tools.GetString(Data, 13, length);
            //Level = DataPackager.GetHostData32(Data, 14 + length);
            var A1 = Data[13 + length];
            var A2 = Data[14 + length];
            if (A2 == 0)
                Level = A1 / 2;
            else
                Level = (A1 - 128) / 2 + A2 * 64;

            this.Data = Data;
        }
    }


    public class ProcessViewLevelMsg : Message
    {
        public short Flag { get; private set; }
        /// <summary>
        /// 玩家编号
        /// </summary>
        public long ID { get; private set; }
        public string Name { get; private set; }
        public int Level { get; private set; }
        public byte[] Version { get; private set; }

        public ProcessViewLevelMsg(byte[] Data)
        {
            int length = DataPackager.GetHostData16(Data, 10);
            int A1 = Data[16 + length];
            int A2 = Data[17 + length];
            if (Data[15 + length] == 0)
            {
                Level = A1 / 2;
            }
            else
                Level = A1 - 128 + A2 * 64;

        }
    }


    public class LoginSuccessMsg1 : Message
    {
        public short Flag { get; private set; }
        /// <summary>
        /// 玩家编号
        /// </summary>
        public long ID { get; private set; }
        public string Name { get; private set; }
        public int Level { get; private set; }
        public byte[] Version { get; private set; }

        public LoginSuccessMsg1(byte[] Data)
        {
            MessageType = MessageTypeEnum.LoginSuccess1;
            Type = 0x000187DA;

            //  Flag = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(Data, 0));
            ID = IPAddress.NetworkToHostOrder(BitConverter.ToInt64(Data, 27));
            Version = Data.Skip(35).Take(1).ToArray();
            int length = DataPackager.GetHostData16(Data, 40);
            Name = Tools.GetString(Data, 42, length);
            //Level = DataPackager.GetHostData32(Data, 14 + length);


            this.Data = Data;
        }
    }



    /// <summary>
    /// 传送返回消息
    /// </summary>
    public class TransmitMsg : Message
    {
        public Map CurrentMap { get; private set; }
        public TransmitMsg(byte[] Data)
        {
            MessageType = MessageTypeEnum.TransmitMap;
            Type = 0x00018AFD;
            this.Data = Data;
            CurrentMap = Maps.GetMap((ushort)IPAddress.NetworkToHostOrder(BitConverter.ToInt16(Data, 1)));
        }
    }

    public class MonsterRefreshedMsg : Message
    {
        public Point Location { get; set; }
        public string Name { get; set; }
        public Map CurrentMap { get; set; }
        public long ID { get; set; }

        public MonsterRefreshedMsg(byte[] Data)
        {
            MessageType = MessageTypeEnum.MonsterRefreshed;
            Type = 0x0001BDBD;
            this.Data = Data;
            try
            {
                ID = IPAddress.NetworkToHostOrder(BitConverter.ToInt64(Data, 0));
                short nameLength = 0;
                int x, y, index = 0;

                index += 13;
                nameLength = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(Data, index));
                index += 2;
                Name = Tools.GetString(Data, index, nameLength);

                index += nameLength + 7;
                if (Data[index] < 0x80)
                {
                    index++;
                }
                else
                {
                    index += 2;
                }

                CurrentMap = Maps.GetMap((ushort)IPAddress.NetworkToHostOrder(BitConverter.ToInt16(Data, index)));
                index += 3;
                x = DataPackager.GetHostData16(Data, index) / 25; //29
                index += 2;
                y = DataPackager.GetHostData16(Data, index) / 25; //29
                Location = new Point(x, y);
            }
            catch
            {
            }
        }
    }

    public class MonsterFoundedMsg : Message
    {
        public List<Monster> Monsters = new List<Monster>();

        public MonsterFoundedMsg(Map currentMap, byte[] Data)
        {
            if (currentMap == null) { return; }
            var mapData = DataPackager.GetNetworkData((short)currentMap.ID);
            MessageType = MessageTypeEnum.MonsterFounded;
            Type = 0x00018b05;
            this.Data = Data;

            int index = 4;
            int count = DataPackager.GetHostData16(Data, index);//怪物数量
            index += 2;

            for (var i = index; i < Data.Length - 13; i++)
            {
                bool searched = true;
                for (var j = i; j < i + 13; j++)
                {
                    if (Data[j] == 0) { searched = false; break; }
                }
                if (!searched) { continue; }
                index = i;
                Monster m = new Monster();
                m.InstanceID = DataPackager.GetHostData64(Data, index); index += 8;
                m.Version = Data.Skip(index).Take(1).ToArray();
                index += 5;
                var nameLength = DataPackager.GetHostData16(Data, index);//怪物名称
                if (nameLength <= 0) { return; }
                index += 2;
                if (index + nameLength > Data.Length) { return; }
                m.Name = Tools.GetString(Data, index, nameLength);
                index += nameLength;//跳过怪物名称
                if (index > Data.Length - 2) { return; }

                for (var j = index; j < Data.Length; j++)//查找地图编号
                {
                    searched = true;
                    for (var k = 0; k < mapData.Length; k++)
                    {
                        if (mapData[k] != Data[j + k]) { searched = false; break; }
                    }
                    if (searched) { index = j; break; }
                }
                if (!searched) { return; }
                index += 3;
                int x = DataPackager.GetHostData16(Data, index) / 25;
                index += 2;
                int y = DataPackager.GetHostData16(Data, index) / 25;
                index += 18;
                m.Location = new Point(x, y);
                Monsters.Add(m);
                i = index;
            }
        }
    }

    public class MonsterMovedMsg : Message
    {
        public long MoverID { get; private set; }
        public Point Location { get; private set; }

        public MonsterMovedMsg(byte[] Data)
        {
            MessageType = MessageTypeEnum.MonsterMoved;
            this.Data = Data;
            MoverID = DataPackager.GetHostData64(Data, 0);
            int x = DataPackager.GetHostData16(Data, 9) / 25;//8
            int y = DataPackager.GetHostData16(Data, 11) / 25;//10
            Location = new Point(x, y);
        }
    }

    public class ResultMsg : Message
    {
        public string DataType { get; set; }
        public string ResultText { get; set; }
        public ResultMsg(byte[] data)
        {
            MessageType = MessageTypeEnum.ServerResult;
            Data = data;
            //int length = DataPackager.GetHostData16(data, 0);
            //DataType = Tools.GetString(data, 2, length);
            //length = 2 + DataType.Length + 2;
            //ResultText = Tools.ConvertChar(Tools.GetString(data, length, data.Length - length));
            ResultText = Tools.ConvertChar(Tools.GetString(data));
        }
    }

    public class UnderAttackMsg : Message//怪物攻击玩家的消息
    {
        /// <summary>
        /// 攻击者编号
        /// </summary>
        public long AttackerID { get; set; }
        /// <summary>
        /// 攻击目标编号
        /// </summary>
        public long TargetID { get; set; }
        /// <summary>
        /// 伤害
        /// </summary>
        public int Damage { get; set; }
        /// <summary>
        /// 玩家当前血量
        /// </summary>
        public int CurrentHP { get; set; }

        public UnderAttackMsg(byte[] Data)
        {
            //MessageType = MessageTypeEnum.Attack;
            //this.Data = Data;
            //TargetID = DataPackager.GetHostData64(Data, 0);
            //AttackerID = DataPackager.GetHostData64(Data, 10);
            ////byte A1 = Data[25];
            ////byte A2 = Data[26];
            ////Damage = (A1 - 128) / 2 + (A2 * 64);
            //byte A1 = Data[24];     //data长度30
            //Damage = A1 / 2;
            //A1 = Data[25];
            //byte A2 = Data[26];

            //CurrentHP = (A1 - 128) / 2 + (A2 * 64);
            MessageType = MessageTypeEnum.Attack;
            this.Data = Data;
            TargetID = DataPackager.GetHostData64(Data, 0);
            AttackerID = DataPackager.GetHostData64(Data, 10);
            //Damage = DataPackager.GetHostData32(Data, 21);
            //MonsterCurrentHP = DataPackager.GetHostData32(Data, 25);

            int A1 = Data[24];
            int A2 = Data[25];
            if (Data.Length == 28)
            {
                A1 = Data[Data.Length - 4];
                A2 = Data[Data.Length - 3];
                Damage = A1 / 2;
                CurrentHP = A2 / 2;

            }
            else
            {
                A1 = Data[Data.Length - 5];
                Damage = A1 / 2;
                //A1 = Data[25];
                //A2 = Data[26];
                A1 = Data[Data.Length - 4];
                A2 = Data[Data.Length - 3];
                if (A2 == 0)
                {
                    CurrentHP = A1 / 2;
                }
                else
                    CurrentHP = (A1 - 128) / 2 + (A2 * 64);
            }


        }
    }

    public class AttackMonsterMsg : Message//玩家攻击怪物的消息
    {
        /// <summary>
        /// 攻击者编号
        /// </summary>
        public long AttackerID { get; set; }
        /// <summary>
        /// 技能编号
        /// </summary>
        public int SkillID { get; set; }

        /// <summary>
        /// 伤害及怪物数据
        /// </summary>
        public List<Tuple<long, int, int>> AttackDatas { get; set; }

        public AttackMonsterMsg(byte[] Data)
        {
            AttackDatas = new List<Tuple<long, int, int>>();
            MessageType = MessageTypeEnum.AttackMonster;
            this.Data = Data;
            AttackerID = DataPackager.GetHostData64(Data, 0);
            int count = DataPackager.GetHostData16(Data.Skip(12).Take(2).ToArray(), 0);//怪物数量
            int index = 14;
            for (var i = 0; i < count; i++)
            {
                long InstanceID = DataPackager.GetHostData64(Data, index);
                index += 10;
                int A1 = Data[index];
                index += 1;
                int A2 = Data[index];
                index += 1;
                int damage = (A1 - 128) / 2 + (A2 * 64);
                A1 = Data[index];
                index += 1;
                A2 = Data[index];
                index += 2;
                int currentHP = (A1 - 128) / 2 + (A2 * 64);
                AttackDatas.Add(new Tuple<long, int, int>(InstanceID, damage, currentHP));
            }
        }
    }

    public class AttackMsg : Message//玩家攻击怪物的消息
    {
        /// <summary>
        /// 攻击者编号
        /// </summary>
        public long AttackerID { get; set; }
        /// <summary>
        /// 攻击目标编号
        /// </summary>
        public long TargetID { get; set; }
        /// <summary>
        /// 伤害
        /// </summary>
        public int Damage { get; set; }
        /// <summary>
        /// 怪物当前血量
        /// </summary>
        public int CurrentHP { get; set; }

        public AttackMsg(byte[] Data)
        {
            MessageType = MessageTypeEnum.Attack;
            this.Data = Data;
            TargetID = DataPackager.GetHostData64(Data, 0);
            AttackerID = DataPackager.GetHostData64(Data, 9);
            //Damage = DataPackager.GetHostData32(Data, 21);
            //MonsterCurrentHP = DataPackager.GetHostData32(Data, 25);
            int A1, A2;

            A1 = Data[Data.Length - 4];
            A2 = Data[Data.Length - 3];
            CurrentHP = (A1 - 128) / 2 + (A2 * 64);

            if (Data.Length == 28)
            {
                A1 = Data[Data.Length - 6];
                A2 = Data[Data.Length - 5];
                Damage = (A1 - 128) / 2 + (A2 * 64);
            }
            //else if (Data.Length == 27)
            //{
            //    A1 = Data[Data.Length - 2];
            //    A2 = Data[Data.Length - 1];
            //    CurrentHP = (A1 - 128) / 2 + (A2 * 64);

            //    A1 = Data[Data.Length - 5];
            //    A2 = Data[Data.Length - 4];
            //    Damage = (A1 - 128) / 2 + (A2 * 64);
            //}

            if (CurrentHP < 0) { CurrentHP = 0; }
        }
    }

    public class PlayerMovedMsg : Message
    {
        public long MoverID { get; private set; }
        public Point Location { get; private set; }
        public byte[] MoveData { get; private set; }

        public PlayerMovedMsg(byte[] Data)
        {
            MessageType = MessageTypeEnum.PlayerMoved;
            this.Data = Data;
            MoverID = DataPackager.GetHostData64(Data, 0);
            int x = DataPackager.GetHostData16(Data, 9) / 25;
            int y = DataPackager.GetHostData16(Data, 11) / 25;
            Location = new Point(x, y);
            MoveData = Data.Skip(14).ToArray();
        }
    }

    public class HeathPointChangedMsg : Message
    {
        public long OwnerID { get; private set; }
        public int CurrentHP { get; private set; }
        public int TotalHP { get; private set; }

        public HeathPointChangedMsg(byte[] Data)
        {
            MessageType = MessageTypeEnum.HeathPointChanged;
            this.Data = Data;
            OwnerID = DataPackager.GetHostData64(Data, 0);
            byte A1, A2;
            A1 = Data[Data.Length - 4];
            A2 = Data[Data.Length - 3];
            CurrentHP = (A1 - 80) / 2 + (A2 * 64);

            A1 = Data[Data.Length - 2];
            A2 = Data[Data.Length - 1];
            TotalHP = (A1 - 80) / 2 + (A2 * 64);
            //CurrentHP = DataPackager.GetHostData32(Data, 8);
            //TotalHP = DataPackager.GetHostData32(Data, 12);
        }
    }

    public class PlayerFoundedMsg : Message
    {
        public long ID { get; private set; }
        public string Name { get; private set; }
        public int Level { get; private set; }
        public int MapID { get; private set; }
        public Point Location { get; private set; }
        public int CurrentHP { get; private set; }
        public int TotalHP { get; private set; }
        public int CurrentMP { get; private set; }
        public int TotalMP { get; private set; }

        public PlayerFoundedMsg(byte[] Data)
        {
            MessageType = MessageTypeEnum.PlayerFounded;
            this.Data = Data;
            ID = DataPackager.GetHostData64(Data, 18);
            int length = DataPackager.GetHostData32(Data, 28);
            Name = Tools.GetString(Data, 32, length);
            Level = DataPackager.GetHostData32(Data, 32 + length);
            int x = DataPackager.GetHostData16(Data, 36 + length);
            int y = DataPackager.GetHostData16(Data, 38 + length);
            Location = new Point(x, y);
            CurrentHP = DataPackager.GetHostData32(Data, 40 + length);
            TotalHP = DataPackager.GetHostData32(Data, 44 + length);
            CurrentMP = DataPackager.GetHostData32(Data, 48 + length);
            TotalMP = DataPackager.GetHostData32(Data, 52 + length);
        }
    }

    public class MpChangedMsg : Message
    {
        public long ID { get; private set; }
        public int CurrentMP { get; private set; }

        public MpChangedMsg(byte[] Data)
        {
            MessageType = MessageTypeEnum.MpChanged;
            this.Data = Data;
            ID = DataPackager.GetHostData64(Data, 0);
            byte a, b;
            a = Data[9];
            if (Data.Length == 11)
            {
                b = Data[10];
                CurrentMP = (a - 128) / 2 + (b * 64);
            }
            else
                CurrentMP = a / 2;


        }
    }

    public class HpChangedMsg : Message
    {
        public long ID { get; private set; }
        public int CurrentHP { get; private set; }

        public HpChangedMsg(byte[] Data)
        {
            MessageType = MessageTypeEnum.HpChanged;
            this.Data = Data;
            ID = DataPackager.GetHostData64(Data, 0);
            byte A1, A2, A3;
            if (Data.Length == 10)
            {
                A1 = Data[Data.Length - 1];
                CurrentHP = A1 / 2;
            }
            else if (Data[8] == 0x1c)
            {
                A1 = Data[Data.Length - 3];
                A2 = Data[Data.Length - 2];
                A3 = Data[Data.Length - 1];
                CurrentHP = (A1 - 128) / 2 + (A2 + (A3 - 1) * 128) * 64;
            }
            else
            {
                A1 = Data[Data.Length - 2];
                A2 = Data[Data.Length - 1];
                CurrentHP = (A1 - 128) / 2 + (A2 * 64);
            }

            //CurrentHP = (ushort)DataPackager.GetHostData16(Data, 10) / 4;
        }
    }

    public class GoldChangedMsg : Message
    {
        public int GoldCount { get; private set; }
        public byte[] GoldID { get; private set; }
        public GoldChangedMsg(byte[] Data)
        {
            MessageType = MessageTypeEnum.GoldChanged;
            this.Data = Data;
            byte A1 = Data[0];
            byte A2 = 1;
            if (Data.Length > 1)
                A2 = Data[1];
            byte A3 = 1;
            if (Data.Length > 2)
                A3 = Data[2];
            byte A4 = 1;
            if (Data.Length == 4)
                A4 = Data[3];

            GoldID = Data.Skip(0).Take(Data.Length).ToArray();
            GoldCount = (A1 - 128) / 2 + (A2 + (A3 - 1 + (A4 - 1) * 128) * 128) * 64;
        }
    }

    /// <summary>
    /// 获得物品
    /// </summary>
    public class ItemGetedMsg : Message
    {
        static byte[] equipData = new byte[] { 0x07, 0x30, 0x5F, 0x30, 0x5F, 0x30, 0x5F, 0x30 };
        public Thing Item { get; private set; }
        public long InstanceID { get; private set; }

        public ItemGetedMsg(byte[] Data)
        {
            MessageType = MessageTypeEnum.ItemCountChanged;
            this.Data = Data;
            InstanceID = DataPackager.GetHostData64(Data, 0);
            var version = Data.Skip(8).Take(1).ToArray();
            var ids = Data.Skip(9).Take(3).ToList();
            ids.Insert(0, 0);
            //ids.Add(0);
            uint id = (uint)DataPackager.GetHostData32(ids.ToArray(), 0);
            //var data = DataPackager.GetHostData64(Data, Data.Length - 4 - 8);
            //if (data == 0x07305f305f305f30)//装备
            //{

            //}
            Item = Thing.GetThing(id);
            if (Item == null)
            {
                Item = new Thing { ID = (uint)id, Name = "未知物品" };
            }

            if (Tools.Search(Data, Data.Length, equipData))
            {
                Item.IsEquipment = true;
            }
            //if (Item.Name == "未知物品" && Data.Length > 35)//装备
            //{
            //    Equipment equipment = new Equipment { ID = Item.ID, Name = Item.Name };
            //    equipment.IsEximious = Data[12] == 1;
            //    equipment.EximiousCount = Data[19];
            //    Item = equipment;
            //}
            Item.Version = version;
            Item.InstanceID = InstanceID;
            Item.Count = 1;
            Item.IsEximious = Data[12] == 1;
        }
    }

    /// <summary>
    /// 物品数量改变
    /// </summary>
    public class ItemCountChangedMsg : Message
    {
        public Thing Item { get; private set; }
        public long InstanceID { get; private set; }

        public ItemCountChangedMsg(byte[] Data)
        {
            MessageType = MessageTypeEnum.ItemCountChanged;
            this.Data = Data;
            InstanceID = DataPackager.GetHostData64(Data, 0);
            var ids = Data.Skip(9).Take(3).ToList();
            ids.Insert(0, 0);
            uint id = (uint)DataPackager.GetHostData32(ids.ToArray(), 0);
            Item = Thing.GetThing(id);
            if (Item == null)
            {
                Item = new Thing { ID = (uint)id, Name = "未知物品" };
            }
            Item.InstanceID = InstanceID;
            Item.Count = Data.Skip(12).First() / 2;
        }
    }

    public class ItemDropedMsg : Message
    {
        public int Count { get; private set; }
        public Thing DropedItem { get; private set; }
        /// <summary>
        /// 所属玩家编号
        /// </summary>
        public long OwnerID { get; private set; }
        public uint TypeID { get; private set; }
        public short X { get; private set; }
        public short Y { get; private set; }
        public string Name { get; private set; }

        public ItemDropedMsg(byte[] Data)
        {
            MessageType = MessageTypeEnum.ItemDroped;
            this.Data = Data;

            var typeDatas = Data.Skip(9).Take(3).ToList();
            typeDatas.Insert(0, 0);
            TypeID = (uint)DataPackager.GetHostData32(typeDatas.ToArray(), 0);
            //int length = DataPackager.GetHostData16(Data, 18);
            // Name = Tools.GetString(typeDatas.ToArray(), 0);
            DropedItem = Thing.GetThing(TypeID);
            if (DropedItem == null)
            {
                DropedItem = new Thing { Name = "未知物品", ID = (uint)TypeID };
                //if (TypeID > 1000000)//分类编号大于100万为卓越物品
                //{
                //    DropedItem.Name = "卓越装备";
                //}
            }
            DropedItem.InstanceID = DataPackager.GetHostData64(Data, 0);
            Count = DataPackager.GetHostData32(Data, 15);
            OwnerID = DataPackager.GetHostData64(Data, Data.Length - 25);
            short length = DataPackager.GetHostData16(Data, 14);
            X = DataPackager.GetHostData16(Data, Data.Length - 6);
            Y = DataPackager.GetHostData16(Data, Data.Length - 4);
        }
    }

    public class RideMsg : Message
    {
        public bool IsRide { get; private set; }
        public long PlayerID { get; private set; }

        public RideMsg(byte[] Data)
        {
            MessageType = MessageTypeEnum.Ride;
            this.Data = Data;
            PlayerID = DataPackager.GetHostData64(Data, 0);
            IsRide = BitConverter.ToBoolean(Data, 12);
        }
    }

    /// <summary>
    /// 捡到物品
    /// </summary>
    public class ItemPickupedMsg : Message
    {
        public uint TypeID { get; private set; }
        public long InstanceID { get; private set; }
        public Thing GetedItem { get; private set; }
        public ushort thingid { get; private set; }
        public int thingids { get; private set; }

        public ItemPickupedMsg(byte[] Data)
        {
            //00 01 97 14 84 D9 E5 BC B6 D3 AA F9 A0 01 86 BA 55 00 00 BA 03 
            MessageType = MessageTypeEnum.ItemPickuped;
            this.Data = Data;
            var typeDatas = Data.Skip(9).Take(3).ToList();
            var thingID = Data[10];
            // thingid = DataPackager.GetHostData64(Data, 11);
            typeDatas.Insert(0, 0);
            TypeID = (uint)DataPackager.GetHostData32(typeDatas.ToArray(), 0);

            thingid = (ushort)DataPackager.GetHostData16(Data, 10);
            thingids = Data[9];

            InstanceID = DataPackager.GetHostData64(Data, 0);
            GetedItem = Thing.GetThing(TypeID);
            if (GetedItem == null)
            {
                //if (thingid == 42415 || thingid == 63150 || thingid == 34479 || thingid == 46511 || thingid == 50351 || thingid == 44450 || thingid == 47004 || thingid == 36777 || thingid == 65448 || thingid == 44713 || thingid == 48809 || thingid == 52649 || thingid == 46748)
                //    GetedItem = new Thing { Name = "卓越弓手装备", ID = (uint)TypeID };
                //else

                //    GetedItem = new Thing { Name = "未知物品", ID = (uint)TypeID, InstanceID = InstanceID };
                ////if (TypeID > 1000000)//分类编号大于100万为卓越装备
                ////{
                ////    GetedItem.Name = "卓越装备";
                ////}
                GetedItem = new Thing { Name = "未知物品", ID = (uint)TypeID };
            }
            GetedItem.InstanceID = InstanceID;
            GetedItem.Version = Data.Skip(8).Take(1).ToArray();
        }
    }

    public class PickupItemMsg : Message
    {
        public string Name { get; private set; }
        public uint TypeID { get; private set; }

        public PickupItemMsg(byte[] Data)
        {
            this.Data = Data;
            int length = DataPackager.GetHostData16(Data, 18);
            Name = Tools.GetString(Data, 20, length);
            TypeID = (uint)DataPackager.GetHostData32(Data.Skip(19).Take(length).ToList().ToArray(), 0);
        }
    }

    public class SignCountMsg : Message
    {
        public int Count { get; set; }
        public SignCountMsg(byte[] data)
        {
            //     Count = DataPackager.GetHostData16(data, 0);
        }
    }


    public class SellEquipmentMsg : Message
    {
        public long InstanceID { get; private set; }

        public SellEquipmentMsg(byte[] Data)
        {
            InstanceID = DataPackager.GetHostData64(Data, 0);
        }
    }

    public class CleanBackpackMsg : Message
    {
        static byte[] equipData = new byte[] { 0x07, 0x30, 0x5F, 0x30, 0x5F, 0x30, 0x5F, 0x30 };
        /// <summary>
        /// 背包格子数量
        /// </summary>
        public int PackageCount { get; private set; }
        public long[] InstanceID { get; private set; }
        public uint[] TypeID { get; private set; }
        public Thing[] GetedItem { get; private set; }
        int i;
        /// <summary>
        /// 物品数量
        /// </summary>
        public int ThingNum { get; private set; }
        public byte[] Versions { get; private set; }

        public CleanBackpackMsg(byte[] Data, Player player)
        {
            PackageCount = Data[0] / 2;
            ThingNum = DataPackager.GetHostData16(Data, 1);

            GetedItem = new Thing[ThingNum];
            int index = 3;
            for (var i = 0; i < ThingNum; i++)
            {
                GetedItem[i] = new Thing();
                GetedItem[i].InstanceID = DataPackager.GetHostData64(Data, index); index += 8;
                GetedItem[i].Version = Data.Skip(index).Take(1).ToArray(); index++;
                var typeDatas = Data.Skip(index).Take(3).ToList(); index += 3;
                typeDatas.Insert(0, 0);
                var typeID = (uint)DataPackager.GetHostData32(typeDatas.ToArray(), 0);
                GetedItem[i].ID = typeID;
                var item = Thing.GetThing(typeID);
                if (item == null)
                {
                    GetedItem[i].Name = "未知物品";
                }
                else
                {
                    GetedItem[i].Name = item.Name;
                }
                GetedItem[i].Count = Data[index] / 2; index++;
                index += 35;
            }
            return;

            //InstanceID = new long[100];
            //TypeID = new uint[100];

            //for (i = 0; i < Data.Length - 10; i++)
            //{
            //    Versions = Data.Skip(i).Take(1).ToArray();
            //    #region 旧代码
            //    if (Versions[0] == player.Version[0])
            //    {
            //        InstanceID[ThingNum] = DataPackager.GetHostData64(Data, i - 8);
            //        typeDatas = Data.Skip(i + 1).Take(3).ToList();
            //        typeDatas.Insert(0, 0);
            //        TypeID[ThingNum] = (uint)DataPackager.GetHostData32(typeDatas.ToArray(), 0);
            //        GetedItem[ThingNum] = Thing.GetThing(TypeID[ThingNum]);
            //        if (GetedItem[ThingNum] == null)
            //        {
            //            GetedItem[ThingNum] = new Thing { Name = "未知物品", ID = (uint)TypeID[ThingNum] };

            //        }
            //        GetedItem[ThingNum].Count = Data.Skip(i + 4).First() / 2;
            //        GetedItem[ThingNum].InstanceID = InstanceID[ThingNum];
            //        GetedItem[ThingNum].Version = Versions;
            //        ThingNum++;
            //    }
            //    else if (Versions[0] == 123)
            //    {
            //        InstanceID[ThingNum] = DataPackager.GetHostData64(Data, i - 8);
            //        typeDatas = Data.Skip(i + 1).Take(3).ToList();
            //        typeDatas.Insert(0, 0);
            //        TypeID[ThingNum] = (uint)DataPackager.GetHostData32(typeDatas.ToArray(), 0);
            //        GetedItem[ThingNum] = Thing.GetThing(TypeID[ThingNum]);
            //        GetedItem[ThingNum].InstanceID = InstanceID[ThingNum];
            //        ThingNum++;
            //    }
            //    #endregion
            //}
        }

        public CleanBackpackMsg(byte[] Data)
        {
            List<Thing> list = new List<Thing>();
            PackageCount = Data[0] / 2;
            ThingNum = DataPackager.GetHostData16(Data, 1);

            GetedItem = new Thing[ThingNum];
            int index = 3;
            int lastIndex = 0;
            for (var i = index; i < Data.Length - 12; i++)
            {
                bool searched = true;
                for (var j = i; j < i + 12; j++)
                {
                    if (Data[j] == 0) { searched = false; break; }
                }
                if (!searched) { continue; }
                index = i;
                var datas = Data.Skip(lastIndex).Take(index - lastIndex).ToArray();
                if (Tools.Search(datas, datas.Length, equipData))
                {
                    list.Last().IsEquipment = true;
                }
                lastIndex = i;
                var getedItem = new Thing();
                getedItem.InstanceID = DataPackager.GetHostData64(Data, index); index += 8;
                getedItem.Version = Data.Skip(index).Take(1).ToArray(); index++;
                var typeDatas = Data.Skip(index).Take(3).ToList(); index += 3;
                typeDatas.Insert(0, 0);
                var typeID = (uint)DataPackager.GetHostData32(typeDatas.ToArray(), 0);
                getedItem.ID = typeID;
                var item = Thing.GetThing(typeID);
                if (item == null)
                {
                    getedItem.Name = "未知物品";
                }
                else
                {
                    item.Version = getedItem.Version;
                    item.InstanceID = getedItem.InstanceID;
                    getedItem = item;
                }

                getedItem.Count = Data[index] / 2; index++;
                list.Add(getedItem);
                i = index;
            }
            GetedItem = list.ToArray();
        }
    }

    public class LevelUpMsg : Message
    {
        public int Level { get; set; }
        public long PlayerID { get; private set; }
        public LevelUpMsg(byte[] data)
        {
            PlayerID = DataPackager.GetHostData64(data, 0);
            //var A1 = data[data.Length - 2];
            //var A2 = data[data.Length - 1];
            var A1 = data[9];
            var A2 = data[10];
            if (A2 == 0)
            {
                Level = A1 / 2;
            }
            else
            {
                A2 = data[10];
                Level = (A1 - 128) / 2 + (A2 * 64);
            }
        }
    }
    /// <summary>
    /// 交易锁定
    /// </summary>
    public class LockTradeMsg : Message
    {
        /// <summary>
        /// 锁定交易的玩家编号
        /// </summary>
        public long InvitePlayerID { get; private set; }
        public ushort InviteTrue { get; private set; }


        public LockTradeMsg(byte[] data)
        {
            MessageType = MessageTypeEnum.LockTrade;
            this.Data = data;
            InvitePlayerID = DataPackager.GetHostData64(Data, 0);
            InviteTrue = data[data.Length - 1];
        }
    }

    /// <summary>
    /// 同意交易
    /// </summary>
    public class AgreeTradeMsg : Message
    {

        public AgreeTradeMsg(byte[] data)
        {
            MessageType = MessageTypeEnum.AgreeTrade;
            this.Data = data;
        }
    }



    /// <summary>
    /// 交易锁定
    /// </summary>
    public class ProcessMailDataMsg : Message
    {
        /// <summary>
        /// 奖励编号
        /// </summary>
        public long ThingID { get; private set; }
        public int ThingNum { get; private set; }

        /// <summary>
        /// 有附件的信的编号
        /// </summary>
        public List<byte[]> MailsID { get; set; }

        public ProcessMailDataMsg(byte[] data)
        {
            MessageType = MessageTypeEnum.MailData;
            this.Data = data;
            MailsID = new List<byte[]>();
            // ThingID[] = DataPackager.GetHostData64(Data, 0);
            ThingNum = 0;
            ThingID = 0;

            int index = 2;
            var length = 0;
            int count = data[index++];//信件数量
            for (int i = 0; i < count; i++)
            {
                var id = data.Skip(index).Take(9).ToArray(); index += 9;
                length = DataPackager.GetHostData16(Data, index);//信件类型长度
                index += 2 + length;
                length = DataPackager.GetHostData16(Data, index);//信件标题长度
                index += 2 + length + 9;
                if (data[index++] == 1)//有附件
                {
                    index += 4;//附件物品类型编号
                    MailsID.Add(id);
                }
            }
        }
    }

    public class ProcessTreasureData : Message
    {
        public long[] InstanceID { get; private set; }
        public uint[] TypeID { get; private set; }
        public Thing[] GetedItem { get; private set; }
        int i;
        public int ThingNum { get; private set; }
        public byte[] Versions { get; private set; }

        public ProcessTreasureData(byte[] data, Player player)
        {

            MessageType = MessageTypeEnum.Treasure;
            this.Data = data;
            var typeDatas = Data.Skip(10).Take(3).ToList();
            ThingNum = 0;

            InstanceID = new long[10];
            TypeID = new uint[10];
            GetedItem = new Thing[10];
            for (i = 0; i < Data.Length - 5; i++)
            {
                Versions = Data.Skip(i).Take(2).ToArray();
                if (Versions[0] == player.Version[0] && Versions[1] == player.Version[1])
                {
                    InstanceID[ThingNum] = DataPackager.GetHostData64(Data, i - 8);
                    typeDatas = Data.Skip(i + 2).Take(3).ToList();
                    typeDatas.Insert(0, 0);
                    TypeID[ThingNum] = (uint)DataPackager.GetHostData32(typeDatas.ToArray(), 0);
                    GetedItem[ThingNum] = Thing.GetThing(TypeID[ThingNum]);
                    if (GetedItem[ThingNum] == null)
                    {
                        GetedItem[ThingNum] = new Thing { Name = "未知物品", ID = (uint)TypeID[ThingNum] };

                    }
                    GetedItem[ThingNum].InstanceID = InstanceID[ThingNum];
                    ThingNum++;
                }
            }

        }
    }

    public class ProcessTitleData : Message
    {
        public byte[] Title { get; private set; }
        public ProcessTitleData(byte[] data)
        {
            MessageType = MessageTypeEnum.Title;
            this.Data = data;
            Title = Data.Skip(1).Take(3).ToArray();
        }
    }

    /// <summary>
    /// 已经学会的技能
    /// </summary>
    public class SkillLearnedMsg : Message
    {
        public List<Skill> LearnedSkills { get; set; }
        public SkillLearnedMsg(byte[] Data)
        {
            this.Data = Data;
            MessageType = MessageTypeEnum.SkillLearned;
            LearnedSkills = new List<Skill>();
            int index = 4;
            if (BitConverter.ToInt16(Data.Take(2).ToArray(), 0) == 0)
            {
                index = 2;
            }
            byte count = Data.Skip(index).First();//技能数量
            index++;

            for (byte i = 0; i < count; i++)
            {
                index += 9;
                var skillBytes = Data.Skip(index).Take(3).ToList();
                index += 7;
                skillBytes.Insert(0, 0);
                int id = DataPackager.GetHostData32(skillBytes.ToArray(), 0);
                var skill = Skills.SkillsDict.Values.FirstOrDefault(f => f.ID == id);
                if (skill != null)
                {
                    LearnedSkills.Add(skill);
                }
            }
        }
    }

    /// <summary>
    /// 剩余点数
    /// </summary>
    public class PointHavedMsg : Message
    {
        /// <summary>
        /// 剩余点数
        /// </summary>
        public int PointCount { get; set; }
        /// <summary>
        /// 力量
        /// </summary>
        public int Str { get; set; }
        /// <summary>
        /// 敏捷
        /// </summary>
        public int Agi { get; set; }
        /// <summary>
        /// 体力
        /// </summary>
        public int Phy { get; set; }
        /// <summary>
        /// 智力
        /// </summary>
        public int Int { get; set; }

        public PointHavedMsg(byte[] Data)
        {
            this.Data = Data;
            Str = Data[1] / 2;
            Phy = Data[2] / 2;
            Agi = Data[3] / 2;
            Int = Data[4] / 2;
            PointCount = (Data[5] - 128) / 2 + (Data[6] * 64);
        }

        public override string ToString()
        {
            return "剩余点数：" + PointCount + " 当前属性：力量" + Str + " 敏捷" + Agi + " 体力" + Phy + " 智力" + Int;
        }
    }
}


